import pygame, math, random
from Controls import *
from Constants import *
import Game
# import Spawn, Particle
import EscapePlayer, EscapeObstacle


'''

need number text states, animations places for polish
reset if wrong animation
correct feedback

better problem generator
save list of obstacles/questions

boosts, boost at end

balance


'''



class EscapeGame(Game.Game):
	'''The game object.'''
	def __init__(self, size, loc, sound):
		'''Initializes the game.'''
		Game.Game.__init__(self, size, loc, sound)

		#gameplay variables
		self.score = 0
		self.death_line = 0

		self.question_timer = 0
		self.next_question_timer = 0
		self.wait_for_obstacle = False

		self.first_number = 0
		self.current_number_str = ''
		self.next_number = 0
		self.answer = 0

		self.first_number_text = None
		self.current_number_text = None
		self.next_number_text = None

		self.obstacle_types = []

		#background
		self.background = ESCAPE_IMAGES["background"]
		self.floor = ESCAPE_IMAGES["floor"]

		#game objects
		self.player = None
		self.obstacle = None

		#object lists
		# self.spawns = []#dust?
		# self.bg_spawns = []#little rocks left/front
		# self.fg_spawns = []#big rocks left/front

		#hud
		#self.hud = EscapeHud.EscapeHud()

	def newlevel(self, leveldata=""):
		'''Interprets a loaded level file's data into a new level. Prepares objects for a new level.'''
		#reset game states
		self.leveldata = leveldata
		self.active = True
		self.endgame = False
		self.wingame = False
		self.pause = False
		self.reset = False

		self.score = 0
		self.death_line = 0

		self.question_timer = 0
		self.next_question_timer = 120
		self.wait_for_obstacle = False

		self.first_number = int(random.random() * 20) + 10
		self.current_number_str = ''
		self.next_number = 0
		self.answer = self.first_number

		self.first_number_text = fonts[48].render(str(self.first_number), 1, (0,255,255))

		self.player = EscapePlayer.EscapePlayer()
		self.obstacle = EscapeObstacle.EscapeObstacle()

		#parse and interpret data
		# data = [o.split(',') for o in leveldata.split(';')]
		# for part in data:
			# pass
			# if part[0] == "spawn":
				# self.spawns.append(Spawn.Spawn((int(part[1]), int(part[2])), Particle.Particle, **dict([tuple(p.split('=')) for p in part[4].split('|')])))


		#test stuff directly

		# self.spawns.append(Spawn.Spawn((320,240), Particle.Particle))

	def handleevent(self, event):
		'''Interprets the given event.'''
		Game.Game.handleevent(self, event)
		if event.type == pygame.KEYDOWN:
			number = number_key(event.key)
			if number == -1:
				return
			controls[number] = True
			new_events[number] = True

			self.edit_number(number)

		elif event.type == pygame.KEYUP:
			number = number_key(event.key)
			if number == -1:
				return
			controls[number] = False
			new_events[number] = True

	def new_obstacle(self):
		'''Creates a new obstacle.'''
		self.obstacle.reset(self)
		self.player.new_obstacle()
		self.question_timer = self.obstacle.rect.left - self.player.rect.right

		self.current_number_str = ''
		self.next_number = random.randrange(1,11)
		self.answer = self.first_number + self.next_number

		operator = '+'
		if self.next_number < 0:
			operator = '-'

		self.first_number_text = fonts[48].render(str(self.first_number), 1, (0,255,255))
		self.next_number_text = fonts[48].render(operator + ' ' + str(self.next_number) + ' =', 1, (0,255,255))
		self.current_number_text = None

	def show_answer(self):
		self.first_number = self.answer
		self.first_number_text = fonts[48].render(str(self.first_number), 1, (0,255,255))

	def edit_number(self, number):
		if len(number) == 1:
			if self.current_number_str == '0':
				self.current_number_str = ''
			self.current_number_str += number
		else:
			self.current_number_str = self.current_number_str[:-1]

		#reset if wrong
		if len(self.current_number_str) == len(str(self.answer)) and int(self.current_number_str) != self.answer:
			# feedback wrong (show that it's wrong first)
			self.current_number_str = ''

		self.current_number_text = fonts[48].render(self.current_number_str, 1, (0,255,255))

	def update(self, delta):
		'''Updates all game objects.'''
		# if self.reset:
			# return

		#interpret game-specific events
		if new_events[k_backspace] and controls[k_backspace]:
			if self.question_timer > 0 and not self.player.correct:
				self.edit_number('')

		#game update
		self.death_line += ESCAPE_PLAYER_DEFAULT_SPD

		if self.question_timer > 0 and not self.player.correct and len(self.current_number_str) > 0:
			if int(self.current_number_str) == self.answer:
				self.player.correct = True

		if self.question_timer > 0:
			self.question_timer = self.obstacle.rect.left - self.player.rect.right
			if self.question_timer <= 0:
				self.question_timer = 0
				self.wait_for_obstacle = True
				self.show_answer()
		elif self.next_question_timer > 0:
			self.next_question_timer -= 1
			if self.next_question_timer == 0:
				self.new_obstacle()
		elif self.wait_for_obstacle:
			if self.obstacle.rect.right <= self.death_line:
				self.next_question_timer = int(random.random() * 90) + 60
				self.wait_for_obstacle = False

		#object update
		self.obstacle.update(self)

		self.player.update(self)

		# for s in self.spawns:
			# s.update()

		#check game status
		if self.player.rect.left >= ESCAPE_GOAL_DISTANCE:
			self.wingame = True
			self.active = False
		elif self.player.rect.left < self.death_line:
			self.reset = True
			self.active = False

		#calculate camera displacement (for scrolling screens)
		x = self.player.rect.right - ESCAPE_PLAYER_SCREEN_TETHER
		if x < self.death_line:
			x = self.death_line
		self.camdisp = (x, 0)

		#post-update reset values
		pass

		#debug print everything
		# print ESCAPE_GOAL_DISTANCE - self.player.rect.left
		# p = 0
		# for s in self.spawns:
			# p += len(s.particles)
		# print p

	def draw(self, surf):
		'''Draws all game objects.'''
		self.camsurf.blit(black, self.camdisp)

		#background
		x = -(self.camdisp[0] * ESCAPE_BG_SPD) % ESCAPE_BG_WIDTH - ESCAPE_BG_WIDTH
		while x < resolution[0]:
			self.camsurf.blit(self.background, (x, 0))
			self.camsurf.blit(self.background, (x, ESCAPE_BG_HEIGHT))
			self.camsurf.blit(self.background, (x, 2 * ESCAPE_BG_HEIGHT))
			x += ESCAPE_BG_WIDTH

		x = -(self.camdisp[0] * ESCAPE_FLOOR_SPD) % ESCAPE_FLOOR_WIDTH - ESCAPE_FLOOR_WIDTH
		while x < resolution[0]:
			self.camsurf.blit(self.floor, (x, ESCAPE_FLOOR_TOP))
			x += ESCAPE_FLOOR_WIDTH

		# self.camsurf.blit(self.background, (-self.camdisp[0] % resolution[0] - resolution[0], 0))
		# self.camsurf.blit(self.background, (-self.camdisp[0] % resolution[0], 0))

		self.obstacle.draw(self.camsurf, self.camdisp)

		self.player.draw(self.camsurf, self.camdisp)

		#text
		if self.first_number_text:
			self.camsurf.blit(self.first_number_text, ESCAPE_FIRST_NUMBER_LOC)
		if self.question_timer > 0:
			self.camsurf.blit(self.next_number_text, ESCAPE_NEXT_NUMBER_LOC)
			if len(self.current_number_str) > 0:
				self.camsurf.blit(self.current_number_text, ESCAPE_CURRENT_NUMBER_LOC)

		surf.blit(self.camsurf, self.loc)
